package com.dragon.loan.service;

import cn.hutool.core.util.IdcardUtil;
import com.alibaba.fastjson.JSON;
import com.dragon.account.entity.PrCodeTable;
import com.dragon.account.service.PrCodeTableService;
import com.dragon.app.marvel2.NewMarvelCoreService;
import com.dragon.common.constant.Constant;
import com.dragon.common.service.BaseService;
import com.dragon.common.util.IDUtil;
import com.dragon.loan.common.Constants;
import com.dragon.loan.entity.AcLoanApplyInfo;
import com.dragon.loan.entity.AcLoanApplyLinkman;
import com.dragon.loan.entity.McamAcLoanApplyImageInfo;
import com.dragon.loan.repository.AcLoanApplyInfoRepository;
import com.fintech.common.util.RedisUtils;
import com.fintech.user.entity.User;
import com.fintech.user.service.UserService;
import com.marvels.approve.process.dto.ProtocolTemplateInfoDTO;
import com.marvels.approve.process.service.IProcessService;
import com.marvels.common.exception.MarvelsBusinessException;
import com.marvels.common.utils.MarvelsLogUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service
public class AcLoanApplyInfoServiceImpl extends BaseService<AcLoanApplyInfo, Long>  implements AcLoanApplyInfoDragonService{
	@Autowired
	private AcLoanApplyInfoRepository acLoanApplyInfoRepository;
	
	@Autowired
	private AcIdentityMapperMd5Service acIdentityMapperMd5Service;

	@Autowired
	private UserService userService;
	@Autowired
	private PrCodeTableService prCodeTableService;
	@Autowired
	private AcCaseStatusTraceService acCaseStatusTraceService;
	@Autowired
	private AcLoanApplyLinkmanService acLoanApplyLinkmanService;
	@Autowired
	private AcLoanApplyBxInfoService acLoanApplyBxInfoService;
	@Autowired
	private NewMarvelCoreService newMarvelCoreService;
	@Autowired
	private IProcessService processService;
	
	private static final String MARRIED_ID = "2";// 已婚
	
	public AcLoanApplyInfo findByLoanId(String loanId){
		return acLoanApplyInfoRepository.findByLoanId(loanId);
	}
	
	public AcLoanApplyInfo apply(AcLoanApplyInfo acLoanApplyInfo) {
		
		//1.1 分布式锁防前端重复提交贷款申请
		String custIdCard = acLoanApplyInfo.getCustIdCard();
		String key = custIdCard + "input";
		Boolean lockSuccess = RedisUtils.getInstance().isLockSuccess(acLoanApplyInfo.getCustIdCard()+"input", Constant.CONSUMERNAME);
		
		// 1.2 检查是否有多笔在途贷款(除去车险分期，其它都不允许有多笔在途),如果有则直接返回前端重复申请
//		boolean custHasApplyingRecord = true;
//		if (!Constant.PRODUCT_TYPE_CXFQ.equals(acLoanApplyInfo.getProductType() + "")) {
//			custHasApplyingRecord = isCustHasApplyingRecord(custIdCard);
//		} else{
//			//车险进件前面已经拦截（applyservice.regist()中），这里直接不拦截了
//			custHasApplyingRecord = false;
//		}
//		if (custHasApplyingRecord) {
//			if (lockSuccess)
//				RedisUtils.getInstance().del(key);
//			throw new RuntimeException("重复提交申请");
//		}
		
		//1.3 以下为初始化贷款记录的 一些状态
		if (Constants.LOAN_TEMPORARY_STATUS.equals(acLoanApplyInfo.getStatus())) {
			acLoanApplyInfo.setStatus(Constants.LOAN_TEMPORARY_STATUS);
		} else {
			acLoanApplyInfo.setStatus(Constants.LOAN_STATUS_J01);
		}
		acLoanApplyInfo.setApplyTime(Calendar.getInstance().getTime());
		acLoanApplyInfo.setCreateTime(Calendar.getInstance().getTime());
		acLoanApplyInfo.setUpdateTime(Calendar.getInstance().getTime());
		
		try {
			if (lockSuccess) {
				makeTag(acLoanApplyInfo);//设置 makeTag 
				// 判断走新核心的开关是否打开 
				if(newMarvelCoreService.isMarvelStart(null, null)){
					acLoanApplyInfo.setGoNewMarvels(new Byte("1"));
				}

				if(null == acLoanApplyInfo.getBirthDate()) {
					Date birthDate = IdcardUtil.getBirthDate(acLoanApplyInfo.getCustIdCard()).toCalendar().getTime();
					acLoanApplyInfo.setBirthDate(birthDate);
				}
				
				//1.4 保存贷款记录
				acLoanApplyInfo = save(acLoanApplyInfo);
				
				//1.5 插入MD5加密后的身份证号跟手机号
				String userId = acLoanApplyInfo.getUserId();
				if (!StringUtils.isEmpty(userId)) {
					User user = userService.queryUserById(Integer.parseInt(userId));
					if (user != null)
						acIdentityMapperMd5Service.insertByIdCardAndMobile(acLoanApplyInfo.getCustIdCard(),
								user.getMobileNo());
				}
			}
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().info("保存贷款信息出错,loan="+JSON.toJSONString(acLoanApplyInfo));
			throw new RuntimeException(e);
		} finally {
			if (lockSuccess)
				RedisUtils.getInstance().del(key);
		}
		
		//1.6 记录贷款流水
		if (!Constants.LOAN_TEMPORARY_STATUS.equals(acLoanApplyInfo.getStatus())) {
			PrCodeTable prCodeTable = prCodeTableService.getCodeTable("PROC_STS_DSC",Constants.LOAN_STATUS_J01);
			if (null != prCodeTable) {
				acCaseStatusTraceService.saveCaseStatusTrace(acLoanApplyInfo.getLoanId(), prCodeTable.getDesc(), new Date(), Constants.LOAN_STATUS_J01);
			}
		}
		
		//1.7 录入联系人
		if (!CollectionUtils.isEmpty(acLoanApplyInfo.getAcLoanApplyLinkmans())) 
			acLoanApplyLinkmanService.save(acLoanApplyInfo.getLoanId(), acLoanApplyInfo.getAcLoanApplyLinkmans());
		
		//1.8 录入保单信息
		if (!CollectionUtils.isEmpty(acLoanApplyInfo.getAcLoanApplyBxInfos())) 
			acLoanApplyBxInfoService.save(acLoanApplyInfo.getLoanId(),acLoanApplyInfo.getAcLoanApplyBxInfos());
		
		return acLoanApplyInfo;
	}

	public AcLoanApplyInfo updateApply(AcLoanApplyInfo acLoanApplyInfo) {
		
		//1 修改贷款记录
		acLoanApplyInfo.setUpdateTime(new Date());
		updateByLoanId(acLoanApplyInfo);
		
		//2 如果是已婚，配偶信息存在，原先没有保存的，这次重新保存
		if (org.apache.commons.lang3.StringUtils.isNotBlank(acLoanApplyInfo.getMateName())
				|| org.apache.commons.lang3.StringUtils.isNotBlank(acLoanApplyInfo.getMateMobile())) {
			Long count = acLoanApplyLinkmanService.queryLinkmanCount(acLoanApplyInfo.getLoanId(), acLoanApplyInfo.getMateMobile());
			if (count ==0) {
				// 保存配偶联系人信息
				AcLoanApplyLinkman acLoanApplyLinkman = new AcLoanApplyLinkman();
				acLoanApplyLinkman.setLoanId(acLoanApplyInfo.getLoanId());
				acLoanApplyLinkman.setLinkmanId(IDUtil.generaterLinkmanId());
				acLoanApplyLinkman.setLinkmanName(acLoanApplyInfo.getMateName());
				acLoanApplyLinkman.setLinkmanMobile(acLoanApplyInfo.getMateMobile());
				if(MARRIED_ID.equals(acLoanApplyInfo.getMarriageId())) {
					acLoanApplyLinkman.setRelationId(Constant.MATE_CODE_ID);
					acLoanApplyLinkman.setRelationName("配偶");
				}else {
					acLoanApplyLinkman.setRelationId("14");
					acLoanApplyLinkman.setRelationName("紧急联系人");
				}
				acLoanApplyLinkman.setRelationType("0");
				acLoanApplyLinkman.setCreateTime(new Date());
				acLoanApplyLinkman.setUpdateTime(new Date());
				acLoanApplyLinkmanService.save(acLoanApplyLinkman);
			}
		}
		return acLoanApplyInfo;
	}

	public int updateByLoanId(AcLoanApplyInfo acLoanApplyInfo){
		return acLoanApplyInfoRepository.updateByLoanId(acLoanApplyInfo);
	}

	/***
	 * 获取映像文件信息
	 * @return
	 */
	public List<McamAcLoanApplyImageInfo> selectAttachmentInfo(String caseId){
		return acLoanApplyInfoRepository.selectAttachmentInfo(caseId);
	}

	public boolean isCustHasApplyingRecord(String custIdCard) {
		if (!StringUtils.hasText(custIdCard)) {
			throw new RuntimeException("客户身份证号码必输");
		}
		Long count = selectCustApplyingCount(custIdCard);
		if (count > 0) {
			return true;
		}
		return false;
	}
	
	/**
	 * 设置 userTag
	 * wanggang
	 * @param acLoanApplyInfo
	 */
	private void makeTag(AcLoanApplyInfo acLoanApplyInfo) {
		// 针对每一个loan_id在申请表里新增一个用户类型的标签
		// a：新户，第一次申请的用户b：次新户，曾经有过申请，但是没有成功放款的用户；c：旧户，成功放款过的用户；
		// 根据身份证查出之前所有的贷款状态
		try {
			List<String> statusList = acLoanApplyInfoRepository.getStatusByIdCard(acLoanApplyInfo.getCustIdCard());
			String userTag = null;
			for (String status : statusList) {
				userTag = "b";
				if ("A01".equals(status) || "A00".equals(status)) {
					userTag = "c";
					break;
				}
			}
			if (userTag != null)
				acLoanApplyInfo.setUserTag(userTag);
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error("makeTag 出现异常===========>" + acLoanApplyInfo.getLoanId(), e);
		}
	}
	
	/**
	 * 查询客户正在贷款申请中的记录条数
	 * @param custIdCard
	 * @return
	 */
	public Long selectCustApplyingCount(String custIdCard){
		return acLoanApplyInfoRepository.selectCustApplyingCount(custIdCard);
	}

	/* (non-Javadoc)
	 * @see com.dragon.loan.service.AcLoanApplyInfoDragonService#contractContent(java.lang.String)
	 */
	@Override
	public List<ProtocolTemplateInfoDTO> contractContent(String loanId) throws MarvelsBusinessException {
		return processService.getLoanCompactHtml(loanId);
	}
	
}
